﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using vudu.Logica.Excepciones;
using vudu.ClasesDominio;

namespace vudu.Datos.SqlServer
{
    /// <summary>
    /// Clase que hace las operaciones de mantenimiento de la entidad Salon para la base de datos
    /// sqlserver
    /// </summary>
    public class SqlServerSalon
    {
        /// <summary>
        /// Metodo que realiza la llamada al stored procedure para insertar un salon
        /// </summary>
        /// <param name="salon"></param>
        /// <returns></returns>
         public int InsertarSalon(Salon salon,int universidad)
         {
             //se instancia un objeto de tipo conexion y sqlCommand
             //estos se utilizan para acceder a base de datos y ejecutar el stored procedure en sql server
             Conexion miConexion = new Conexion();
             SqlCommand command = new SqlCommand();
             int idEdificio;
             idEdificio = buscarEdificio(salon.Edificio,universidad);
             int validacion = validarSalon(salon, universidad);
             int idInsertado = -1;
             try
             {
                 miConexion.AbrirConexionBd(); //se abre una conexion a base de datos

                 // se completa el objeto comando, con la informacion de la conexion , variables, y nombre del stored procedure.
                 command.Connection = miConexion.ObjetoConexion();
                 command.CommandType = CommandType.StoredProcedure;
                 command.CommandText = "[dbo].[InsertarSalon]";
                 command.CommandTimeout = 10;

                 //variables del stored procedure de sql server.
                 command.Parameters.AddWithValue("@nombre", salon.Nombre);
                 command.Parameters.AddWithValue("@capacidad", salon.Capacidad);
                 command.Parameters.AddWithValue("@tiposalon", salon.Tipo);
                 command.Parameters.AddWithValue("@idedificio",idEdificio);

                 command.Parameters["@nombre"].Direction = ParameterDirection.Input;
                 command.Parameters["@capacidad"].Direction = ParameterDirection.Input;
                 command.Parameters["@tiposalon"].Direction = ParameterDirection.Input;
                 command.Parameters["@idedificio"].Direction = ParameterDirection.Input;

                 if (validacion != 1)
                 {
                     //se ejecuta el comando
                     SqlDataReader reader = command.ExecuteReader();
                     while (reader.Read())
                     {
                         idInsertado = (int)reader[0];
                     }
                     //se lee la variable de tipo output para saber que id fue insertado en base de datos.
                 }
                 else
                 {
                     idInsertado = -2;
                 }
             }
             catch (SqlException)
             {
                 throw new TransaccionFallidaExeption();
             }
             catch (ConexionExeption)
             {
                 throw new ConexionExeption();
             }
             catch (Exception)
             {
                 throw new TransaccionFallidaExeption();
             }

            miConexion.CerrarConexionBd();
            return idInsertado;
        }


        /// <summary>
        /// Metodo que modifica los datos de un salon
        /// </summary>
        /// <param name="salon"></param>
        /// <returns></returns>
         public int ModificarSalon(Salon salon, int universidad)
        {
            //se instancia un objeto de tipo conexion y sqlCommand
            //estos se utilizan para acceder a base de datos y ejecutar el stored procedure en sql server
            Conexion miConexion = new Conexion();
            SqlCommand command = new SqlCommand();
            int retorno;
            int idEdificio;
            idEdificio = buscarEdificio(salon.Edificio, universidad);

            try
            {
                miConexion.AbrirConexionBd(); //se abre una conexion a base de datos

                // se completa el objeto comando, con la informacion de la conexion , variables, y nombre del stored procedure.
                command.Connection = miConexion.ObjetoConexion();
                command.CommandType = CommandType.StoredProcedure;
                command.CommandText = "[dbo].[ModificarSalon]";
                command.CommandTimeout = 10;

                //variables del stored procedure de sql server.
                command.Parameters.AddWithValue("@nombre", salon.Nombre);
                command.Parameters.AddWithValue("@idEdificio", idEdificio);
                command.Parameters.AddWithValue("@capacidad", salon.Capacidad);
                command.Parameters.AddWithValue("@tiposalon", salon.Tipo);
                command.Parameters.AddWithValue("@status", salon.Status);
                command.Parameters.AddWithValue("@idsalon", salon.NumeroSalon);

                command.Parameters["@nombre"].Direction = ParameterDirection.Input;
                command.Parameters["@idEdificio"].Direction = ParameterDirection.Input;
                command.Parameters["@capacidad"].Direction = ParameterDirection.Input;
                command.Parameters["@tiposalon"].Direction = ParameterDirection.Input;
                command.Parameters["@status"].Direction = ParameterDirection.Input;
                command.Parameters["@idsalon"].Direction = ParameterDirection.Input;
                

                //se ejecuta el comando
                command.ExecuteNonQuery();
                retorno = 1;
            }
            catch (SqlException)
            {
                throw new TransaccionFallidaExeption();
                retorno = 0;
            }
            catch (ConexionExeption)
            {
                throw new ConexionExeption();
                retorno = 0;
            }
            catch (Exception)
            {
                throw new TransaccionFallidaExeption();
                retorno = 0;
            }


            miConexion.CerrarConexionBd();
            return retorno;
        }


        /// <summary>
        /// Metodo que consulta los datos de un salon dado un nombre
        /// </summary>
        /// <param name="nombre"></param>
        /// <param name="universidad"></param>
        /// <returns></returns>
        public List<Salon> ConsultarSalonNombre(string nombre, Universidad universidad)
        {
            Conexion miConexion = new Conexion();
            SqlCommand command = new SqlCommand();
            List<Salon> retorno = new List<Salon>();
            try
            {
                miConexion.AbrirConexionBd(); //se abre una conexion a base de datos

                // se completa el objeto comando, con la informacion de la conexion , variables, y nombre del stored procedure.
                command.Connection = miConexion.ObjetoConexion();
                command.CommandType = CommandType.StoredProcedure;
                command.CommandText = "[dbo].[ConsultarSalonNombre]";
                command.CommandTimeout = 10;

                //variables del stored procedure de sql server.
                command.Parameters.AddWithValue("@nombre", nombre);
                command.Parameters.AddWithValue("@iduniversidad", universidad.IdUniv);

                command.Parameters["@nombre"].Direction = ParameterDirection.Input;
                command.Parameters["@iduniversidad"].Direction = ParameterDirection.Input;
                //se ejecuta el comando
                SqlDataReader reader = command.ExecuteReader();
                while (reader.Read())
                {
                    Salon salon = new Salon();

                    salon.NumeroSalon = (int)reader[0];
                    salon.Tipo = (string)reader[1];
                    salon.Nombre = (string) reader[2];
                    salon.Edificio = (string) reader[3];
                    salon.Capacidad = (int) reader[4];
                    salon.Status = (int) reader[5];
                    retorno.Add(salon);
                }

            }
            catch (SqlException)
            {
                throw new TransaccionFallidaExeption();
            }
            catch(ConexionExeption)
            {
                throw new ConexionExeption();       
            }
            catch(Exception)
            {
                throw new TransaccionFallidaExeption();
            }


            miConexion.CerrarConexionBd();
            return retorno;
        }


        /// <summary>
        /// Metodo que consulta los datos de un salon dado un nombre
        /// </summary>
        /// <param name="universidad"></param>
        /// <returns></returns>
        public List<Salon> ConsultarSalonInabilitados(Universidad universidad)
        {
            Conexion miConexion = new Conexion();
            SqlCommand command = new SqlCommand();
            List<Salon> retorno = new List<Salon>();
            try
            {
                miConexion.AbrirConexionBd(); //se abre una conexion a base de datos

                // se completa el objeto comando, con la informacion de la conexion , variables, y nombre del stored procedure.
                command.Connection = miConexion.ObjetoConexion();
                command.CommandType = CommandType.StoredProcedure;
                command.CommandText = "[dbo].[ConsultarSalonInabilitados]";
                command.CommandTimeout = 10;

                command.Parameters.AddWithValue("@iduniversidad", universidad.IdUniv);
                command.Parameters["@iduniversidad"].Direction = ParameterDirection.Input;

                //se ejecuta el comando
                SqlDataReader reader = command.ExecuteReader();
                while (reader.Read())
                {
                    Salon salon = new Salon();

                    salon.NumeroSalon = (int)reader[0];
                    salon.Tipo = (string)reader[1];
                    salon.Nombre = (string)reader[2];
                    salon.Edificio = (string)reader[3];
                    salon.Capacidad = (int)reader[4];
                    salon.Status = (int)reader[5];
                    retorno.Add(salon);
                }

            }
            catch (SqlException)
            {
                throw new TransaccionFallidaExeption();
            }
            catch (ConexionExeption)
            {
                throw new ConexionExeption();
            }
            catch (Exception)
            {
                throw new TransaccionFallidaExeption();
            }

            miConexion.CerrarConexionBd();
            return retorno;
        }


        /// <summary>
        /// Metodo que consulta todos los datos de los salones por edificio
        /// </summary>
        /// <returns></returns>
        public List<Salon> ConsultarSalonEdificio(string edificio, Universidad universidad)
        {
            Conexion miConexion = new Conexion();
            SqlCommand command = new SqlCommand();
            List<Salon> retorno = new List<Salon>();
            try
            {
                miConexion.AbrirConexionBd(); //se abre una conexion a base de datos
                // se completa el objeto comando, con la informacion de la conexion , variables, y nombre del stored procedure.
                command.Connection = miConexion.ObjetoConexion();
                command.CommandType = CommandType.StoredProcedure;
                command.CommandText = "[dbo].[ConsultarSalonEdificio]";

                command.Parameters.AddWithValue("@edificio", edificio);
                command.Parameters.AddWithValue("@iduniversidad", universidad.IdUniv);

                command.Parameters["@edificio"].Direction = ParameterDirection.Input;
                command.Parameters["@iduniversidad"].Direction = ParameterDirection.Input;
                command.CommandTimeout = 10;

                //se ejecuta el comando
                SqlDataReader reader = command.ExecuteReader();
                while (reader.Read())
                {
                    Salon salon = new Salon();
                    salon.NumeroSalon = (int)reader[0];
                    salon.Tipo = (string)reader[1];
                    salon.Nombre = (string)reader[2];
                    salon.Edificio = (string)reader[3];
                    salon.Capacidad = (int)reader[4];
                    salon.Status = (int)reader[5];
                    retorno.Add(salon);
                }

            }
            catch (SqlException)
            {
                throw new TransaccionFallidaExeption();
            }
            catch (ConexionExeption)
            {
                throw new ConexionExeption();
            }
            catch (Exception)
            {
                throw new TransaccionFallidaExeption();
            }


            miConexion.CerrarConexionBd();
            return retorno;
        }


        /// <summary>
        /// Metodo que consulta todos los datos de los salones por tipo
        /// </summary>
        /// <returns></returns>
        public List<Salon> ConsultarSalonTipo(string tipo, Universidad universidad)
        {
            Conexion miConexion = new Conexion();
            SqlCommand command = new SqlCommand();
            List<Salon> retorno = new List<Salon>();
            try
            {
                miConexion.AbrirConexionBd(); //se abre una conexion a base de datos

                
                
                // se completa el objeto comando, con la informacion de la conexion , variables, y nombre del stored procedure.
                command.Connection = miConexion.ObjetoConexion();
                command.CommandType = CommandType.StoredProcedure;
                command.CommandText = "[dbo].[ConsultarSalonTipo]";
                command.CommandTimeout = 10;


                //variables del stored procedure de sql server.
                command.Parameters.AddWithValue("@tipo", tipo);
                command.Parameters.AddWithValue("@iduniversidad", universidad.IdUniv);

                command.Parameters["@tipo"].Direction = ParameterDirection.Input;
                command.Parameters["@iduniversidad"].Direction = ParameterDirection.Input;
                //se ejecuta el comando
                SqlDataReader reader = command.ExecuteReader();
                while (reader.Read())
                {
                    Salon salon = new Salon();
                    salon.NumeroSalon = (int)reader[0];
                    salon.Tipo = (string)reader[1];
                    salon.Nombre = (string)reader[2];
                    salon.Edificio = (string)reader[3];
                    salon.Capacidad = (int)reader[4];
                    salon.Status = (int)reader[5];
                    retorno.Add(salon);
                }

            }
            catch (SqlException)
            {
                throw new TransaccionFallidaExeption();
            }
            catch (ConexionExeption)
            {
                throw new ConexionExeption();
            }
            catch (Exception)
            {
                throw new TransaccionFallidaExeption();
            }


            miConexion.CerrarConexionBd();
            return retorno;
        }

        public List<Edificio> ConsultarEdificio(int universidad)
        {
            Conexion miConexion = new Conexion();
            SqlCommand command = new SqlCommand();
            List<Edificio> retorno = new List<Edificio>();
            try
            {
                miConexion.AbrirConexionBd(); //se abre una conexion a base de datos
                // se completa el objeto comando, con la informacion de la conexion , variables, y nombre del stored procedure.
                command.Connection = miConexion.ObjetoConexion();
                command.CommandType = CommandType.StoredProcedure;
                command.CommandText = "[dbo].[buscarEdificiosPorUniversidad]";
                command.CommandTimeout = 10;

                //variables del stored procedure de sql server.
                command.Parameters.AddWithValue("@id_universidad", universidad);
                command.Parameters["@id_universidad"].Direction = ParameterDirection.Input;
                //se ejecuta el comando
                SqlDataReader reader = command.ExecuteReader();
                while (reader.Read())
                {
                    Edificio miEdificio = new Edificio();
                    miEdificio.Clave = (int)reader[0];
                    miEdificio.Nombre = (String)reader[1];
                    retorno.Add(miEdificio);
                }

            }
            catch (SqlException)
            {
                throw new TransaccionFallidaExeption();
            }
            catch (ConexionExeption)
            {
                throw new ConexionExeption();
            }
            catch (Exception)
            {
                throw new TransaccionFallidaExeption();
            }
            miConexion.CerrarConexionBd();
            return retorno;
        }

        public int buscarSalonHorario(Salon salon)
        {
            Conexion miConexion = new Conexion();
            SqlCommand command = new SqlCommand();
            int idFKSalon = 0;

            try
            {
                miConexion.AbrirConexionBd(); //se abre una conexion a base de datos
                // se completa el objeto comando, con la informacion de la conexion , variables, y nombre del stored procedure.
                command.Connection = miConexion.ObjetoConexion();
                command.CommandType = CommandType.StoredProcedure;
                command.CommandText = "[dbo].[buscarSalonenHorario]";
                command.CommandTimeout = 10;

                //variables del stored procedure de sql server.

                command.Parameters.AddWithValue("@idsalon", salon.NumeroSalon);
                command.Parameters["@idsalon"].Direction = ParameterDirection.Input;
                //se ejecuta el comando
                SqlDataReader reader = command.ExecuteReader();
                while (reader.Read())
                {
                    idFKSalon = (int)reader[0];
                }

            }
            catch (SqlException)
            {
                throw new TransaccionFallidaExeption();
            }
            catch (ConexionExeption)
            {
                throw new ConexionExeption();
            }
            catch (Exception)
            {
                throw new TransaccionFallidaExeption();
            }
            miConexion.CerrarConexionBd();
            return idFKSalon;
        }

        public int buscarEdificio(string edificio,int universidad)
        {
            Conexion miConexion = new Conexion();
            SqlCommand command = new SqlCommand();
            int idEdificio = 0;

            try
            {
                miConexion.AbrirConexionBd(); //se abre una conexion a base de datos
                // se completa el objeto comando, con la informacion de la conexion , variables, y nombre del stored procedure.
                command.Connection = miConexion.ObjetoConexion();
                command.CommandType = CommandType.StoredProcedure;
                command.CommandText = "[dbo].[buscarEdificio]";
                command.CommandTimeout = 10;

                //variables del stored procedure de sql server.
                command.Parameters.AddWithValue("@id_universidad", universidad);
                command.Parameters.AddWithValue("@edificio", edificio);
                command.Parameters["@id_universidad"].Direction = ParameterDirection.Input;
                command.Parameters["@edificio"].Direction = ParameterDirection.Input;
                //se ejecuta el comando
                SqlDataReader reader = command.ExecuteReader();
                while (reader.Read())
                {
                    idEdificio = (int)reader[0];
                }

            }
            catch (SqlException)
            {
                throw new TransaccionFallidaExeption();
            }
            catch (ConexionExeption)
            {
                throw new ConexionExeption();
            }
            catch (Exception)
            {
                throw new TransaccionFallidaExeption();
            }
            miConexion.CerrarConexionBd();
            return idEdificio;
        }

        /// <summary>
        /// Metodo que consulta los datos de un salon dado un nombre
        /// </summary>
        /// <param name="nombre"></param>
        /// <param name="universidad"></param>
        /// <returns></returns>
        public List<Salon> ConsultarSalones(int universidad)
        {
            Conexion miConexion = new Conexion();
            SqlCommand command = new SqlCommand();
            List<Salon> retorno = new List<Salon>();
            try
            {
                miConexion.AbrirConexionBd(); //se abre una conexion a base de datos

                // se completa el objeto comando, con la informacion de la conexion , variables, y nombre del stored procedure.
                command.Connection = miConexion.ObjetoConexion();
                command.CommandType = CommandType.StoredProcedure;
                command.CommandText = "[dbo].[todosLosSalones]";
                command.CommandTimeout = 10;

                //variables del stored procedure de sql server.
                command.Parameters.AddWithValue("@iduniversidad", universidad);

                command.Parameters["@iduniversidad"].Direction = ParameterDirection.Input;
                //se ejecuta el comando
                SqlDataReader reader = command.ExecuteReader();
                while (reader.Read())
                {
                    Salon salon = new Salon();
                  
                    salon.Nombre = (string)reader[0];
                    salon.Tipo = (string)reader[1];
                    salon.Capacidad = (int)reader[2];
                    salon.Edificio = (string)reader[3];
                    salon.NumeroSalon = (int)reader[4];
                    salon.Status = (int)reader[5];
                    
                    retorno.Add(salon);
                }

            }
            catch (SqlException)
            {
                throw new TransaccionFallidaExeption();
            }
            catch (ConexionExeption)
            {
                throw new ConexionExeption();
            }
            catch (Exception)
            {
                throw new TransaccionFallidaExeption();
            }


            miConexion.CerrarConexionBd();
            return retorno;
        }

        /// <summary>
        /// Metodo que modifica los datos de un salon
        /// </summary>
        /// <param name="salon"></param>
        /// <returns></returns>
        public int EliminarSalon(Salon salon)
        {
            //se instancia un objeto de tipo conexion y sqlCommand
            //estos se utilizan para acceder a base de datos y ejecutar el stored procedure en sql server
            Conexion miConexion = new Conexion();
            SqlCommand command = new SqlCommand();
            int retorno;
            int idEdificio = buscarSalonHorario(salon);
            if (idEdificio == 0)
            {
                try
                {
                    miConexion.AbrirConexionBd(); //se abre una conexion a base de datos

                    // se completa el objeto comando, con la informacion de la conexion , variables, y nombre del stored procedure.
                    command.Connection = miConexion.ObjetoConexion();
                    command.CommandType = CommandType.StoredProcedure;
                    command.CommandText = "[dbo].[EliminarSalon]";
                    command.CommandTimeout = 10;

                    //variables del stored procedure de sql server.

                    command.Parameters.AddWithValue("@status", salon.Status);
                    command.Parameters.AddWithValue("@idSalon", salon.NumeroSalon);

                    command.Parameters["@status"].Direction = ParameterDirection.Input;
                    command.Parameters["@idSalon"].Direction = ParameterDirection.Input;


                    //se ejecuta el comando
                    command.ExecuteNonQuery();
                    retorno = 1;
                }
                catch (SqlException)
                {
                    throw new TransaccionFallidaExeption();
                    retorno = 0;
                }
                catch (ConexionExeption)
                {
                    throw new ConexionExeption();
                    retorno = 0;
                }
                catch (Exception)
                {
                    throw new TransaccionFallidaExeption();
                    retorno = 0;
                }


                miConexion.CerrarConexionBd();
            }
            else
            {
                retorno = 0;
            }
            return retorno;
        }

        /// <summary>
        /// Metodo que modifica los datos de un salon
        /// </summary>
        /// <param name="salon"></param>
        /// <returns></returns>
        public int validarSalon(Salon salon, int universidad)
        {
            //se instancia un objeto de tipo conexion y sqlCommand
            //estos se utilizan para acceder a base de datos y ejecutar el stored procedure en sql server
            Conexion miConexion = new Conexion();
            SqlCommand command = new SqlCommand();
            int retorno = -1;

            try
            {
                miConexion.AbrirConexionBd(); //se abre una conexion a base de datos

                // se completa el objeto comando, con la informacion de la conexion , variables, y nombre del stored procedure.
                command.Connection = miConexion.ObjetoConexion();
                command.CommandType = CommandType.StoredProcedure;
                command.CommandText = "[dbo].[validarSalones]";
                command.CommandTimeout = 10;

                //variables del stored procedure de sql server.
                command.Parameters.AddWithValue("@salon", salon.Nombre);
                command.Parameters.AddWithValue("@edificio", salon.Edificio);
                command.Parameters.AddWithValue("@idUniversidad", universidad);

                command.Parameters["@salon"].Direction = ParameterDirection.Input;
                command.Parameters["@edificio"].Direction = ParameterDirection.Input;
                command.Parameters["@idUniversidad"].Direction = ParameterDirection.Input;

               //se ejecuta el comando
                SqlDataReader reader = command.ExecuteReader();
                while (reader.Read())
                {
                    retorno = 1;
                }
            }
            catch (SqlException)
            {
                throw new TransaccionFallidaExeption();
                retorno = 0;
            }
            catch (ConexionExeption)
            {
                throw new ConexionExeption();
                retorno = 0;
            }
            catch (Exception)
            {
                throw new TransaccionFallidaExeption();
                retorno = 0;
            }


            miConexion.CerrarConexionBd();
            return retorno;
        }
        #region Metodos Grupo 5: No borrar
        //Metodo Grupo 5: No eliminar... Es necesario para el crear HorarioClase
        public List<Salon> ConsultarTodosLosSalones()
        {
            Conexion conex = new Conexion();

            List<Salon> salones = new List<Salon>();
            SqlCommand command = new SqlCommand();

            conex.AbrirConexionBd();
            command.Connection = conex.ObjetoConexion();
            command.CommandType = System.Data.CommandType.Text;
            command.CommandText = "SELECT * FROM SALON";
            command.CommandTimeout = 10;

            SqlDataReader reader = command.ExecuteReader();

            while (reader.Read())
            {
                Salon salon = new Salon();
                salon.NumeroSalon = reader.GetInt32(0);
                salon.Tipo = reader["tipo"].ToString();
                salon.Nombre = reader["nombre"].ToString();
                salon.Edificio = reader["edificio"].ToString();
                salon.Capacidad = reader.GetInt32(4);
                salon.Status = reader.GetInt32(5);
                salones.Add(salon);

            }
            reader.Close();
            conex.CerrarConexionBd();
            return salones;
        }

        public Salon ConsultarSalon(String codigo)
        {
            Conexion conex = new Conexion();

            Salon salonesDeClase = new Salon();
            SqlCommand command = new SqlCommand();

            conex.AbrirConexionBd();
            command.Connection = conex.ObjetoConexion();
            command.CommandType = System.Data.CommandType.Text;
            command.CommandText = "SELECT * FROM SALON S WHERE S.id_salon =" + codigo;
            command.CommandTimeout = 10;

            SqlDataReader reader = command.ExecuteReader();

            while (reader.Read())
            {
                Salon salon = new Salon();
                salon.NumeroSalon = reader.GetInt32(0);
                salon.Tipo = reader["tipo"].ToString();
                salon.Nombre = reader["nombre"].ToString();
                //salon.Edificio = reader["edificio"].ToString();
                salon.Capacidad = reader.GetInt32(4);
                salon.Status = reader.GetInt32(5);
                salonesDeClase = salon;

            }
            reader.Close();
            conex.CerrarConexionBd();
            return salonesDeClase;
        }

        #endregion Metodos Grupo 5: No borrar
    
        

    }
}